package com.fare.taluo.application.impl.analyse;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;

import javax.annotation.Resource;

import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.fare.taluo.application.analyse.AirCompanyTrendContrastLineApplication;
import com.fare.taluo.application.fetl.SinglePlaneInfoApplication;
import com.fare.taluo.core.domain.config.channel.SourceEntity;
import com.fare.taluo.core.domain.config.line.FlightInfoEntity;
import com.fare.taluo.em.TimePeriod;
import com.fare.taluo.fetl.domain.entity.SinglePlaneInfoEntity;
import com.fare.taluo.fusionCharts.FusionChartsTemplateModel;
import com.fare.taluo.fusionCharts.SimpleFusionChartsBuilder;
import com.fare.taluo.util.FusionChartsUtil_2;
import com.fare.taluo.util.I18nUtil;
import com.fare.taluo.util.StringUtils;
import com.fare.taluo.util.flightInfo.FlightInfoSortUtil;
import com.fare.taluo.util.flightInfo.SameChannelContrastUtil;
import com.fare.taluo.vo.core.PlaneInfo;
import com.fare.taluo.vo.report.SameChannelContrastVO;
import com.fare.taluo.vo.report.SpreadVo;
import com.fare.taluo.vo.report.XmlVO;
/**
*
 * 核心业务分析说明【航线走势对比】
 * 五大航空公司对同一条航线的每天数据的对比，不关心航班号！
 * 数据来源有  官网、渠道
 * LP_LINE_HOUR 渠道_起点_终点_航班日期(年月日时)_（公司Key  如CA）
 * 时间段筛选，自定义时段优先于AMMDPMND，当AMMDPMND为空时，默认为ALL
 * FusionCharts 报表的生成使用模版类FusionChartsTemplateModel 这是个坑！
 * 
 * 
 * LP_LINE_HOUR 设计的初衷是最新的数据，但是最新不代表是当天抓到的，如果今天引擎挂了，那么最新的数据并不是今天的，而是昨天的
 * 从此表RowKey没有方法得出抓取日期，所以我们对拿出来的数据需要进行二次筛选，第一次，筛选用户所选择的时间段，第二次，过滤出非当天抓取的数据
 * 所以，如果今晚12点之后浏览网页，有可能发生全部数据为空的情况，因为“今天”的任务还没做，昨天的任务被晒选出来了
 * 
 * 有一种可以节省查询时间的方法，当用户时间段选择太宽的时候，查询时间会很费时，但实际上每天某个航线每个航空公司就那么几个航班，时间段都是比较确定和单一的，不可能24个小时都在飞
 * 所以我们可以先罗列所有的航班，得出每个的起飞时间，然后匹对用户选择的时间段，然后得出需要去运算的时间段就可以了，这样可以大大的减少查询时间，当然前提是数据库的航班时间段必须是100%准确的
 * 不然就会漏掉数据
 * 
 * 
 * @author guokenye
 *
 */
@Transactional
@Service("airCompanyTrendContrastLineApplicationImpl")
public class AirCompanyTrendContrastLineApplicationImpl implements AirCompanyTrendContrastLineApplication{
	@Resource(name = "singlePlaneInfoApplication")
	private SinglePlaneInfoApplication singlePlaneInfoApplication;
	@Override
	public String getFusionChartsXMLStr(String fromCity,String toCity,String fromCityCode, String toCityCode,
			String flightStartDate, String flightEndDate, Integer futureDay,
			String[] periods, Integer selfStartPeriods, Integer selfEndPeriods,
			String compareCompanyHbaseKey, String[] comparedCompanyHbaseKeys,
			String dataSourceHbaseKey,String priceType,Locale locale) throws Exception {
		 List<String> flightDate=new ArrayList<String>();//航班日期list
		  Map<String,PlaneInfo> map =  new  HashMap<String,PlaneInfo>();
		 /*//当存在未来天数时，优先级高于指定的时间范围
		 if(futureDay!=null && futureDay.compareTo(new Integer(0))>0){//未来天数大于0
			 flightDate=FusionChartsUtil_2.getDatesStr(//航班日期从今天到未来的n天
					 FusionChartsUtil_2.dateToStr(new Date()), futureDay.intValue());
		 }else {*/
			 System.out.println("进入航班日期");
			 flightDate=FusionChartsUtil_2.getDatesStr(flightStartDate, flightEndDate);
		// }
		 List<String> dates=FusionChartsUtil_2.getDatesStrFormat(flightDate);//去掉时间的“-”
		 System.out.println("日期长度："+dates.size()+"     "+dates.get(0));
		 SourceEntity se=new SourceEntity();//new一个你妹的领域模型
		 List<SourceEntity> sources=new ArrayList<SourceEntity>();
		 sources.add(se.findByCarrierKey(compareCompanyHbaseKey).get(0));
		 if(comparedCompanyHbaseKeys!=null){
			 for(String hKey:comparedCompanyHbaseKeys){
				 if(StringUtils.isNotEmpty(hKey)){
					 sources.add(se.findByCarrierKey(hKey).get(0));
				 }
				
			 }
		 }
		 FusionChartsTemplateModel model=FusionChartsTemplateModel.getNewDefaultInstance();//报表模型
		 model.addChartAttr(FusionChartsTemplateModel.AN_Caption, fromCity+" - "+toCity+(null==I18nUtil.getProperties(locale).get("xmlutil.airlineTrend")? " 航空公司航线走势对比":I18nUtil.getProperties(locale).get("xmlutil.airlineTrend")));
		 //TODO 国际化
		 model.addCategroyLabels(FusionChartsUtil_2.getDatesStrFormatMMdd(flightDate));
		 FlightInfoEntity fe=new FlightInfoEntity();//你妹的领域模型
		 long dataSetId=1000L;
		 for(SourceEntity source:sources){//每个航空公司
			 List<PlaneInfo> sourceData= new ArrayList<PlaneInfo>();//每个公司的数据
			 String channelHbaseKey=null;//渠道
			 if(dataSourceHbaseKey==null || "".equals(dataSourceHbaseKey)){//数据来源，空为官网
				 channelHbaseKey=source.getHbaseKey();//渠道为五大航空公司
			 }else{//渠道
				 channelHbaseKey=dataSourceHbaseKey;//渠道为页面选择的如携程、淘宝等
			 }
			 //分别求出每个公司的属于这个航线的所有航班
			 //为了可以直接的取出航班时间和用户所选时间的交集，大大的加大查询速度
			 List<FlightInfoEntity> flights=fe.findByLine(fromCityCode, toCityCode, source.getCarrierKey());
				 //先根据用户选择的时间段，推算出一个时间范围getEveryHourInTimePersiod，这样除了全选的情况，我们不用每次都去罗列24个小时
				// for(String date:flightDate){//航班日期
			 		//找到所有的符合条件的所有日期下的航班集
					List<SinglePlaneInfoEntity> tempEntityList = singlePlaneInfoApplication.findPlaneInfo(channelHbaseKey, source.getCarrierKey(), fromCityCode, toCityCode, null, null);
					//过滤航班日期
					tempEntityList = SameChannelContrastUtil.filterByDate(tempEntityList,flightDate);
					//过滤时间段
					tempEntityList = SameChannelContrastUtil.timeFilter(periods,tempEntityList);
					if ("lowest".equalsIgnoreCase(priceType)) {
						tempEntityList = SameChannelContrastUtil.getLowestByLineEachDay(tempEntityList, flightDate);
					} else if ("highest".equalsIgnoreCase(priceType)) {
						//否则找到最高价
						tempEntityList = SameChannelContrastUtil.getHighestByLineEachDay(tempEntityList, flightDate);
					}
					if(StringUtils.checkList(tempEntityList)){
						sourceData.addAll(SameChannelContrastUtil.getPlaneInfoList(tempEntityList));
					}
				// }
			 System.out.println("查询sourceData的长度："+sourceData.size()+"    "+sourceData);
			 //查找最低价类型
			 if("lowest".equalsIgnoreCase(priceType)){
				 sourceData=FlightInfoSortUtil.generatePlaneInfosInTodayCrawlOrderByFlightBatch(sourceData, flightDate);
			 }else if("highest".equalsIgnoreCase(priceType)){
			 //查找最高价类型 
				 sourceData=FlightInfoSortUtil.generatePlaneInfosInTodayCrawlOrderByFlightBatchHighestPrice(sourceData, flightDate);
			 }
			 
			 //找出单个渠道价差表格
			 map = SameChannelContrastUtil.getSingleSpreadForm(flightDate,sourceData,map);
			 List<String> prices=//开始提取数值
					 FusionChartsUtil_2.getPriceValueByPlaneInfosAndFormat(sourceData,locale);
			 System.out.println("prices的长度："+prices.size()+"   "+prices);
			 String setsStr=FusionChartsUtil_2.generateDashedByFormat(prices,locale);//完整的Set字符串
			 //构建模型
			 model.createDataSet(dataSetId);
			 model.addDataSetAttr(dataSetId,FusionChartsTemplateModel.AN_Seriesname, (null==I18nUtil.getProperties(locale).get(source.getShortName())? source.getShortName():I18nUtil.getProperties(locale).get(source.getShortName())));
			 model.addSetFullStrIntoDataSet(dataSetId, setsStr);
			 model.addDataSetAttr(dataSetId, FusionChartsTemplateModel.AN_RenderAs, "Line");//以折现展示数据
			 dataSetId++;
		 }
		 

		 model.addStyleToObject("ToolTip", FusionChartsTemplateModel.STYLE_ToolTip_FontSize_15);//全局style
		 model.addStyleToObject("Caption", FusionChartsTemplateModel.STYLE_Caption_FontSize_15);//全局style,标题15
		 String xml=SimpleFusionChartsBuilder.getInstance().buildXMLStr(model);
		 System.out.println("拼接XML字符串："+xml);
		 
		 //获得价差表格list
		
		List<SameChannelContrastVO> spreadVos =  getSpreadListForm(flightDate,map,sources,locale);
		XmlVO xmlvo = new XmlVO();
		xmlvo.setXmlString(xml);
		StringBuffer resultBuffer = new StringBuffer();
		String jsonStr = com.fare.taluo.util.JsonUtil.toJson(spreadVos);
		resultBuffer.append("{\"Total\":"+spreadVos.size()+","+ "\"Rows\":"+jsonStr+","+ "\"Xml\":"+com.fare.taluo.util.JsonUtil.toJson(xmlvo)+"}");	
		String json = resultBuffer.toString();
	    return json;
	}
	private List<SameChannelContrastVO> getSpreadListForm(List<String> flightDate,Map<String,PlaneInfo> map,List<SourceEntity> sources,Locale locale){
		List<SameChannelContrastVO> vos = new ArrayList<SameChannelContrastVO>();
		for (String date : flightDate) {
			int i = 0;
			SameChannelContrastVO vo = new SameChannelContrastVO();
			for (SourceEntity source : sources) {
				
				//设置本航
				if(i == 0){
					PlaneInfo p = map.get(source.getCarrierKey()+"_"+date)==null?null:map.get(source.getCarrierKey()+"_"+date);
					if(null != p){
						vo.setNativeCarrier(null==I18nUtil.getProperties(locale).get(p.getCarrierName())?p.getCarrierName():I18nUtil.getProperties(locale).get(p.getCarrierName()));
						vo.setDate(date);
						vo.setNativePrice(p.getLowerPrice());
					}else{
						vo.setDate(date);
						vo.setNativeCarrier(null==I18nUtil.getProperties(locale).get(source.getShortName())?source.getShortName():I18nUtil.getProperties(locale).get(source.getShortName()));
						vo.setNativePrice(null);
					}
					
				}else{
					//获得非本航的其它航
					PlaneInfo p = map.get(source.getCarrierKey()+"_"+date)==null?null:map.get(source.getCarrierKey()+"_"+date);
					SpreadVo svo = new SpreadVo();
					if(null != p){
						svo.setCarrierName(null==I18nUtil.getProperties(locale).get(p.getCarrierName())?p.getCarrierName():I18nUtil.getProperties(locale).get(p.getCarrierName()));
						if(vo.getNativePrice()==null){
							svo.setSpread(null);
							svo.setSpreadAmount(null);
							svo.setPrice(p.getLowerPrice());
						}else{
							svo.setSpreadAmount(""+(Double.parseDouble(p.getLowerPrice())-Double.parseDouble(vo.getNativePrice())));
							svo.setSpread(SameChannelContrastUtil.getSpreadToString(p.getLowerPrice(),vo.getNativePrice()));
							
							svo.setPrice(p.getLowerPrice());
						}
					}else{
						svo.setCarrierName(null==I18nUtil.getProperties(locale).get(source.getName())?source.getName():I18nUtil.getProperties(locale).get(source.getName()));
						svo.setSpread(null);
						svo.setSpreadAmount(null);
						svo.setPrice(null);
					}
					vo.getContrastList().add(svo);
				}
				i++;
			}
			vos.add(vo);
		}
		return vos;
	}
	
	
	
	
	
	

	/**
	 * 过滤时间段
	 * @author Administrator
	 *
	 */
	class FilterTimePeriod{
		List<TimePeriod>  timePeriods= new ArrayList<TimePeriod>();
		public FilterTimePeriod(String[] periods){
			if(periods==null || periods.length >= 4){
				timePeriods.add(TimePeriod.ALL);
			}else{
				for(String s : periods){
					timePeriods.add(TimePeriod.fromCode(s.trim()));//添加各个指定的时间段
				}
			}
		}
		public boolean filter(PlaneInfo p) throws Exception{
			SimpleDateFormat sdf=new SimpleDateFormat("yyyyMMddHHmmss");
			if(p == null) return false;
			for(TimePeriod t : timePeriods){
				if(t.hasBetweenTime(sdf.parse(p.getFlightBatchStartTime().trim()))){
					return true;
				}
			}
			return false;
		}
		public List<TimePeriod> getTimePeriods() {
			return timePeriods;
		}
	}
	

	
	
	
	
	
	
	
}
